package org.huanmin.handle;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gitee.huanminabc.utils_common.base.ChromeDriverUtil;
import com.gitee.huanminabc.utils_common.exception.UniversalException;
import com.google.common.collect.Maps;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.huanmin.common.client.BaiJiaHaoImg;
import org.huanmin.common.client.OpenGpt;
import org.huanmin.common.global.BaiJiahaoGlobal;
import org.huanmin.model.param.UserInfoParam;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.*;

@Component
@Slf4j
public class BaijiahaoHandle extends HandlerAbs {
    @Value("${baijiahao.login}")
    private String login;

    @Value("${baijiahao.home}")
    private String home;

    @Autowired
    private OpenGpt openGpt;
    @Autowired
    private BaiJiaHaoImg baiJiaHaoImg;

    private Map<String, ChromeDriverUtil> utils = Maps.newConcurrentMap();


    @SneakyThrows
    public void logins(List<UserInfoParam> list)  {
        log.info("开始登录:{}", list);
        for (UserInfoParam userInfoParam : list) {
            //如果已经登录过了那么就不在登录了
            if (BaiJiahaoGlobal.cookieMap.get(userInfoParam.getUserName()) != null) {
                continue;
            }

            ChromeDriverUtil util = createChromeDriver();
            ChromeDriver driver = util.getDriver();
            driver.navigate().to(login); //先登录
            util.sleep(2000);
            WebElement login = driver.findElementByCssSelector(".btnlogin--bI826");  //.pass-form-logo > .account-login
            login.click();
            util.sleep(1000);
            WebElement userLogin = driver.findElementByCssSelector(".pass-form-logo > .account-login");
            userLogin.click();
            //输入: TANGRAM__PSP_4__userName 和 TANGRAM__PSP_4__password
            driver.findElementByCssSelector("#TANGRAM__PSP_4__userName").sendKeys(userInfoParam.getUserName());
            driver.findElementByCssSelector("#TANGRAM__PSP_4__password").sendKeys(userInfoParam.getPassword());
            String checked = driver.findElementByCssSelector("#TANGRAM__PSP_4__memberPass").getAttribute("checked");
            if (checked == null) {
                driver.findElementByCssSelector("#TANGRAM__PSP_4__memberPass").click();
            }
            util.sleep(500);
            driver.findElementByCssSelector("#TANGRAM__PSP_4__submit").click();
            //死循环一直判断是否当前的url是登录成功后的url
            while (true) {
                log.info("检测当前url:{}", driver.getCurrentUrl());
                if (driver.getCurrentUrl().equals(home)) {
                    break;
                }
                Thread.sleep(1000);
            }
            Thread.sleep(1000);
            //检测是否有弹框
            WebElement close = ChromeDriverUtil.wait(driver, 3, ExpectedConditions.presenceOfElementLocated(By.cssSelector(".activity-content .activity-close")));
            if (close != null) {
                close.click();
            }
            Set<Cookie> cookies = driver.manage().getCookies();
            if (!cookies.isEmpty()) {
                BaiJiahaoGlobal.cookieMap.put(userInfoParam.getUserName(), cookies);
            }
            log.info("登录成功:{}", userInfoParam.getUserName());
            driver.close(); //关闭当前页签
            driver.quit();//关闭整个游览器
            util.sleep(1000);
        }
        //保存用户信息
        Map<String,UserInfoParam> userInfos = new HashMap();
        for (UserInfoParam userInfoParam : list) {
            userInfos.put(userInfoParam.getUserName(), userInfoParam);
        }
        BaiJiahaoGlobal.userInfos=userInfos; //不保留历史的用户信息
    }

    @SneakyThrows
    private  ChromeDriverUtil login(String userName)  {
        //如果已经登录过了那么就不在登录了
        if (BaiJiahaoGlobal.cookieMap.isEmpty()){
            throw new UniversalException("请先批量登录");
        }
        log.info("开始登录:{}", userName);


        UserInfoParam userInfoParam = BaiJiahaoGlobal.userInfos.get(userName);
        ChromeDriverUtil util = createChromeDriver();
        ChromeDriver driver = util.getDriver();
        driver.navigate().to(login); //先登录
        util.sleep(2000);
        WebElement login = driver.findElementByCssSelector(".btnlogin--bI826");  //.pass-form-logo > .account-login
        login.click();
        util.sleep(1000);
        WebElement userLogin = driver.findElementByCssSelector(".pass-form-logo > .account-login");
        userLogin.click();
        //输入: TANGRAM__PSP_4__userName 和 TANGRAM__PSP_4__password
        driver.findElementByCssSelector("#TANGRAM__PSP_4__userName").sendKeys(userInfoParam.getUserName());
        driver.findElementByCssSelector("#TANGRAM__PSP_4__password").sendKeys(userInfoParam.getPassword());
        String checked = driver.findElementByCssSelector("#TANGRAM__PSP_4__memberPass").getAttribute("checked");
        if (checked == null) {
            driver.findElementByCssSelector("#TANGRAM__PSP_4__memberPass").click();
        }
        util.sleep(500);
        driver.findElementByCssSelector("#TANGRAM__PSP_4__submit").click();
        //死循环一直判断是否当前的url是登录成功后的url
        while (true) {
            log.info("检测当前url:{}", driver.getCurrentUrl());
            if (driver.getCurrentUrl().equals(home)) {
                break;
            }
            Thread.sleep(1000);
        }
        Thread.sleep(1000);
        //检测是否有弹框
        WebElement close = ChromeDriverUtil.wait(driver, 3, ExpectedConditions.presenceOfElementLocated(By.cssSelector(".activity-content .activity-close")));
        if (close != null) {
            close.click();
        }
        log.info("登录成功:{}", userInfoParam.getUserName());
        return util;
    }

    //批量生成GPT文章
    @SneakyThrows
    public void createBathContent(List<String> list) {
        if (BaiJiahaoGlobal.cookieMap.isEmpty()) {
            throw new UniversalException("请先登录");
        }
        //如果标题的数量和登陆账户的数量不一致那么抛出异常
        if (BaiJiahaoGlobal.userInfos.size() !=list.size()) {
            throw new UniversalException("标题和登录账号的数量不一致:当前登录用户数量:{}", BaiJiahaoGlobal.userInfos.size());
        }

        log.info("开始生成文章:{}", list);

        BaiJiahaoGlobal.titleSet.clear();
        //如果没有重复,那么就添加到set中
        for (String tips : list) {
            //检查标题是否重复
            if (BaiJiahaoGlobal.titleSet.contains(tips)){
                throw new UniversalException("标题重复:{}",tips);
            }
            String content = openGpt.text(tips);
            log.info("请求返回的内容:{}", content);
            JSONObject jsonObject = JSON.parseObject(content);
            JSONArray choices = jsonObject.getJSONArray("choices");
            JSONObject jsonObject1 = choices.getJSONObject(0);
            JSONObject message = jsonObject1.getJSONObject("message");
            String contentPick = message.getString("content");
            log.info("生成的文章:{}", contentPick);
            //如果文章少于500那么就报错
            if (contentPick.length() < 500) {
                throw new UniversalException("{}生成的文章内容过短要求大于500,当前生成的内容长度为:{}", tips, contentPick.length());
            }

            BaiJiahaoGlobal.content.add(contentPick);
            BaiJiahaoGlobal.titleSet.add(tips);
            Thread.sleep(20000); //gpt限制单个账户每隔20秒生成一次
        }

    }

    public void createBathImages(List<String> list) {
        if (BaiJiahaoGlobal.cookieMap.isEmpty()) {
            throw new UniversalException("请先登录");
        }
        //如果标题的数量和登陆账户的数量不一致那么抛出异常
        if (BaiJiahaoGlobal.userInfos.size() !=list.size()) {
            throw new UniversalException("标题和登录账号的数量不一致:当前登录用户数量:{}", BaiJiahaoGlobal.userInfos.size());
        }
        BaiJiahaoGlobal.images.clear();
        String userName = BaiJiahaoGlobal.cookieMap.keySet().stream().findFirst().get();
        for (String title : list) {
            List<String> imgList = baiJiaHaoImg.getImgList(BaiJiahaoGlobal.cookieMap.get(userName), title);
            if (imgList.isEmpty()) {
                throw new UniversalException("获取图片失败:{}", title);
            }
            //如果长度小于3那么获取前面的图片进行补全
            if (imgList.size() < 3) {
                int size = imgList.size();
                for (int i = 0; i < 3 -size; i++) {
                    imgList.add(imgList.get(0));
                }
            }
            String images = imgList.stream().reduce((a, b) -> a + "#1#" + b).get();
            BaiJiahaoGlobal.images.add(images);
        }
    }


    public void bathPush(List<String> list) {
        if (BaiJiahaoGlobal.cookieMap.isEmpty()) {
            throw new UniversalException("请先登录");
        }
        //如果标题的数量和登陆账户的数量不一致那么抛出异常
        if (BaiJiahaoGlobal.userInfos.size() !=list.size()) {
            throw new UniversalException("标题和登录账号的数量不一致:当前登录用户数量:{}", BaiJiahaoGlobal.userInfos.size());
        }


        int titleIndex=0;
        for (Map.Entry<String, UserInfoParam> stringUserInfoParamEntry : BaiJiahaoGlobal.userInfos.entrySet()) {

            //登录
            ChromeDriverUtil util = login(stringUserInfoParamEntry.getKey());

            //获取标题
            String title = list.get(titleIndex++);

            ChromeDriver driver = util.getDriver();
            driver.findElementByCssSelector(".author-info-wrap ~ button").click();
            util.sleep(2000);
            //输入标题
            driver.findElementByCssSelector(".client_pages_edit_components_titleInput   .input-box  > textarea").sendKeys("蒙查查-" + title);
            //切入到iFrame
            WebDriver frame = driver.switchTo().frame(driver.findElementByCssSelector(".edui-editor-iframeholder  iframe"));
            util.sleep(1000);
            //输入内容
            JavascriptExecutor executor = (JavascriptExecutor) frame;


            //内容处理
            context(util, executor, title);
            //给内容添加回车,让内容进行解析,否则页面是乱的
            util.sleep(500);
            frame.findElement(By.tagName("body")).sendKeys("                       \n");
            util.sleep(1000);



            //跳出iFrame ,返回到主页面
            WebDriver webDriver = frame.switchTo().defaultContent();



            //滚动到底部
            JavascriptExecutor executor1 = (JavascriptExecutor) webDriver;


            //单图封面一张
            clickScrollElement(webDriver,".cover-radio-group > label:nth-child(2)");



            //选择封面
            clickScrollElement(webDriver,".bjh-edit-wrap-set > div:nth-child(1) .coverUploaderView");
            util.sleep(2000);
            //选择图片
            ChromeDriverUtil.wait(webDriver, 10, ExpectedConditions.presenceOfElementLocated(By.cssSelector(".cheetah-ui-pro-image-modal-choose-cover > div:nth-child(1)"))).click();
            //点击确认
            ChromeDriverUtil.wait(webDriver, 10, ExpectedConditions.presenceOfElementLocated(By.cssSelector(".cheetah-modal-footer > button:nth-child(2)"))).click();
            log.info("选择封面完成1");
            //等待弹框消失
            ChromeDriverUtil.noExist(webDriver, ExpectedConditions.presenceOfElementLocated(By.cssSelector(".cheetah-modal .cheetah-modal-body")));



            log.info("选择封面2 开始");
            try {//如果系统自动选择了封面,那么就不用选择了,因为元素是不可点击的
                //选择封面
                clickScrollElement(webDriver,".bjh-edit-wrap-set > div:nth-child(2) .coverUploaderView");
                util.sleep(2000);
                //选择图片
                ChromeDriverUtil.wait(webDriver, 10, ExpectedConditions.presenceOfElementLocated(By.cssSelector(".cheetah-ui-pro-image-modal-choose-cover > div:nth-child(2)"))).click();
                //点击确认
                ChromeDriverUtil.wait(webDriver, 10, ExpectedConditions.presenceOfElementLocated(By.cssSelector(".cheetah-modal-footer > button:nth-child(2)"))).click();
            } catch (Exception e) {
            }
            try {
                Actions actions = new Actions(webDriver);
                //发布
                WebElement element2 = webDriver.findElement(By.cssSelector(".editor-component-operator > .op-list > div:nth-child(3)"));
                actions.moveToElement(element2).perform();
                util.sleep(500);
                element2.click();
                //监听2秒,如果弹出了弹框,那么就点击直接发布
                pushPopupClean(webDriver);
                //发布成功后,关闭游览器
                driver.close(); //关闭当前页签
                driver.quit();//关闭整个游览器
                log.info("++++++++++++++++++++++++++++++++++++发布成功:{}", title);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    private void context(ChromeDriverUtil util, JavascriptExecutor executor, String title) {
        String text = BaiJiahaoGlobal.content.poll();
        if (Strings.isBlank(text)){
            throw new UniversalException("内容为空");

        }
        String image = BaiJiahaoGlobal.images.poll();
        if (Strings.isBlank(image)){
            throw new UniversalException("图片为空");
        }
        String[] images = image.split("#1#");



        String[] split = text.split("\n\n");
        int start = 1;
        int content = split.length / 2;
        int end = split.length - 2;

        List<Integer> img = Arrays.asList(start, content, end);

        int indexImg = 0;
        for (int i = 0; i < split.length; i++) {
            //插入文本
            try {
                String[] split1 = split[i].split("\n");
                //全部换位p标签
                for (String line : split1) {
                    executor.executeScript(" " +
                            "        var scr = document.createElement('p');\n" +
                            "         scr.innerText = '" + line + "'; \n " +
                            "        document.body.appendChild(scr);");

                }
            } catch (Exception e) {
                throw new UniversalException(e, "{}", split[i]);
            }
            util.sleep(100);
            //插入图片
            try {
                if (img.contains(i)) {
                    executor.executeScript(" " +
                            "        var scr = document.createElement('img');\n" +
                            "        scr.src = '" + images[indexImg] + "';\n" +
                            "        document.body.appendChild(scr);");
                    indexImg++;
                }
            } catch (Exception e) {
                throw new UniversalException(e, "图片插入失败:{}",images[indexImg]);
            }
        }

    }

    /**
     * 发布时候弹窗优化弹窗关闭
     *
     * @param webDriver
     */
    private void pushPopupClean(WebDriver webDriver) {
        try {
            //如果发布的时候弹出了弹框,那么就点击直接发布
            WebElement element1 = webDriver.findElement(By.cssSelector(".cheetah-modal-content   .cheetah-modal-confirm-content button:nth-child(1)"));
            element1.click();
        } catch (Exception e) {
        }
    }


    private void clickScrollElement(WebDriver webDriver,String cssSelector ) {
        //滚动到第一张选择图片
        JavascriptExecutor executor1 = (JavascriptExecutor) webDriver;

        double maxScrollHeight = parseDouble(executor1.executeScript("var result=document.getElementsByTagName(\"html\")[0].scrollHeight; return result;"));
        double scrollHeight = parseDouble( executor1.executeScript("var result=document.getElementsByTagName(\"html\")[0].scrollTop; return result;"));
        while (scrollHeight < maxScrollHeight) {
            executor1.executeScript("window.scrollTo(document.getElementsByTagName(\"html\")[0].scrollTop,document.getElementsByTagName(\"html\")[0].scrollTop+100)");
            //单图封面一张
            Actions actions = new Actions(webDriver);
            try {
                WebElement element = webDriver.findElement(By.cssSelector(cssSelector));
                actions.moveToElement(element).perform();
                element.click();
            } catch (Exception e) {
                scrollHeight = parseDouble(executor1.executeScript("var result=document.getElementsByTagName(\"html\")[0].scrollTop; return result;"));
                continue;
            }
            return;
        }
        throw new UniversalException("clickScrollElement->滚动到底部没有找到这个需要点击的元素:{}",cssSelector);
    }

    //将object转换为字符串,然后在转换int
    private static Double parseDouble(Object obj) {
        if (obj == null) {
            return 0.0;
        }
        return Double.parseDouble(obj.toString());
    }

}
